home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / prg_casm / snip9611.zip / T_CLEAN.C < prev    next >
C/C++ Source or Header  |  1996-11-24  |  9KB  |  294 lines

  1. /* +++Date last modified: 28-Sep-1996 */
  2.  
  3. /*
  4. **  Remove all files older than a given date from the current directory
  5. **  and (optionally) all subdirectories
  6. **
  7. **  public domain by Bob Stout
  8. **
  9. **  uses SCALDATE.C & FTIME.C from SNIPPETS
  10. **  also uses TODAY.C & FDATE.C from SNIPPETS
  11. */
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <io.h>
  17. #include <dos.h>
  18. #include <ctype.h>
  19. #include <time.h>
  20. #include "sniptype.h"
  21. #include "dirport.h"
  22. #include "ftime.h"
  23. #include "scaldate.h"
  24. #include "unistd.h"
  25.  
  26. #if (defined(_MSC_VER) && (_MSC_VER >= 700)) || (defined(__SC__))
  27.  /* Make FP_xxx macros lvalues as in older versions */
  28.  #undef FP_SEG
  29.  #undef FP_OFF
  30.  #define FP_SEG(fp)    ((unsigned)((unsigned long)(fp) >> 16))
  31.  #define FP_OFF(fp)    ((unsigned)(fp && 0xffff))
  32. #endif
  33.  
  34. #define show(s) fputs((s), stderr)
  35.  
  36. /*
  37. **  Switches and globals
  38. */
  39.  
  40. Boolean_T recurse = False_, gobble = False_;
  41. Boolean_T ignore = False_, noaction = False_;
  42.  
  43. long kill_date = 0L;
  44. FILE *log = NULL;
  45. long file_date;
  46.  
  47. /*
  48. **  Local prototypes
  49. */
  50.  
  51. static void usage(Boolean_T errstat);
  52. static void clean_dir(char *path);
  53. static void do_dir(char *path);
  54. static void RMfile(char *fname);
  55. static void RMdir(char *dname);
  56. static int  log_printf(char *str, char *arg);
  57.  
  58. /*
  59. **  T_CLEAN - Deletes all files and (optionally) subdirectories
  60. */
  61.  
  62. int main(int argc, char *argv[])
  63. {
  64.       int i, j, span;
  65.       Boolean_T found_dir = False_;
  66.       void (*clean_func)(char *) = clean_dir;
  67.  
  68.       for (i = 1; i < argc; ++i)          /* Check for switches         */
  69.       {
  70.             if (NULL == strchr("-/", *argv[i]))
  71.                   continue;               /* Assume it's a filename     */
  72.             for (j = 1; argv[i][j] ; ++j) /* Traverse nested switches   */
  73.             {
  74.                   switch (toupper(argv[i][j]))
  75.                   {
  76.                   case 'R':
  77.                         clean_func = do_dir;
  78.                         break;
  79.  
  80.                   case 'G':
  81.                         gobble = True_;
  82.                         break;
  83.  
  84.                   case 'I':
  85.                         ignore = True_;
  86.                         break;
  87.  
  88.                   case 'N':
  89.                         noaction = True_;
  90.                         break;
  91.  
  92.                   case '?':
  93.                         fputs("*** Help ***\n", stderr);
  94.                         usage(False_);
  95.                         break;
  96.  
  97.                   case 'L':
  98.                         if (0 == strlen(&argv[i][++j]))
  99.                               log = stdout;
  100.                         else
  101.                         {
  102.                               log = fopen(strupr(&argv[i][j]), "w");
  103.                               if (NULL == log)
  104.                               {
  105.                                     fprintf(stderr, "*** Unable to open "
  106.                                           "logfile, %s\n", &argv[i][j]);
  107.                                     return Error_;
  108.                               }
  109.                         }
  110.                         j += strlen(&argv[i][j]) - 1; /* End of switch  */
  111.                         break;
  112.  
  113.                   case 'T':
  114.                         if (0 == strlen(&argv[i][++j]))
  115.                         {
  116.                               fputs("*** No time specified ***\n", stderr);
  117.                               usage(Error_);                /* Oops     */
  118.                         }
  119.                         span = atoi(&argv[i][j]);
  120.                         kill_date = today() - (long)(span);
  121.                         j += strlen(&argv[i][j]) - 1; /* End of switch  */
  122.                         break;
  123.  
  124.                   default:
  125.                         fprintf(stderr, "*** Bad switch - %c ***",
  126.                               argv[i][j]);
  127.                         usage(Error_);
  128.                   }
  129.             }
  130.       }
  131.       if (0L == kill_date)
  132.             kill_date = today() - 14L;
  133.  
  134.       for (i = 1; i < argc; ++i)          /* Scan filenames             */
  135.       {
  136.             if (strchr("/-", *argv[i]))
  137.                   continue;
  138.             found_dir = True_;
  139.             clean_func(argv[i]);
  140.       }
  141.       if (!found_dir)
  142.       {
  143.             fputs("*** No directory specified ***\n", stderr);
  144.             usage(True_);
  145.       }
  146.       return EXIT_SUCCESS;
  147. }
  148.  
  149. /*
  150. **  Tell 'em they messed up
  151. */
  152.  
  153. static void usage(Boolean_T errstat)
  154. {
  155.       if (errstat)
  156.             fputc('\a', stderr);
  157.       show("Usage: T_CLEAN directory [...directory] [-tN] [-l[LOGFILE]] "
  158.             "[-rgin?]\n");
  159.       show("switches: -tN          Remove only files older than N days\n"
  160.             "                       (default = 14 days)\n");
  161.       show("          -l[LOGFILE]  Create named log file or (default) log to "
  162.             "the console\n");
  163.       show("          -r           Recurse subdirectories\n");
  164.       show("          -g           Gobble (delete) empty subdirectories\n");
  165.       show("          -i           Ignore special file attributes "
  166.             "(CAUTION!)\n");
  167.       show("          -n           No Action, display/log proposed "
  168.             "deletions\n");
  169.       show("          -?           Display help (this message)\n");
  170.       exit(errstat);
  171. }
  172.  
  173. /*
  174. **  Clean all files from a directory
  175. */
  176.  
  177. static void clean_dir(char *path)
  178. {
  179.       char rmpath[FILENAME_MAX], *rmfile;
  180.       DOSFileData fbuf;
  181.       unsigned attrib = (ignore) ? _A_ANY : 0;
  182.  
  183.       strcpy(rmpath, path);
  184.       if ('\\' != LAST_CHAR(rmpath))
  185.             strcat(rmpath, "\\");
  186.       rmfile = &rmpath[strlen(rmpath)];
  187.       strcpy(rmfile, "*.*");
  188.       if (0 == FIND_FIRST(rmpath, attrib, &fbuf)) do
  189.       {
  190.             strcpy(rmfile, ff_name(&fbuf));
  191.             if (0 != getdatef(rmpath, &file_date))
  192.             {
  193.                   log_printf("Unable to get date of %s\n", rmpath);
  194.                   continue;
  195.             }
  196.             if (ignore)
  197.             {
  198.                   union REGS regs;
  199.                   struct SREGS sregs;
  200.  
  201.                   regs.x.ax = 0x4300;
  202.                   regs.x.dx = FP_OFF((char FAR *)rmpath);
  203.                   segread(&sregs);
  204.                   sregs.ds  = FP_SEG((char FAR *)rmpath);
  205.                   intdosx(®s, ®s, &sregs);
  206.                   if (!regs.x.cflag)
  207.                   {
  208.                         regs.x.ax  = 0x4301;
  209.                         regs.x.cx &= ~(_A_RDONLY | _A_HIDDEN | _A_SYSTEM);
  210.                         intdosx(®s, ®s, &sregs);
  211.                         if (regs.x.cflag)
  212.                               log_printf("Unable to ignore attributes "
  213.                                     "of %s\n", rmpath);
  214.                   }
  215.             }
  216.             if (kill_date > file_date)
  217.                   RMfile(rmpath);
  218.       } while (0 == FIND_NEXT(&fbuf));
  219. }
  220.  
  221. /*
  222. **  Process directories
  223. */
  224.  
  225. static void do_dir(char *path)
  226. {
  227.       char search[FILENAME_MAX], new[FILENAME_MAX];
  228.       DOSFileData ff;
  229.  
  230.       strcpy(search, path);
  231.       if ('\\' != LAST_CHAR(search))
  232.             strcat(search, "\\");
  233.       strcat(search, "*.*");
  234.       if (Success_ == FIND_FIRST(search, _A_ANY, &ff)) do
  235.       {
  236.             if (ff.attrib & _A_SUBDIR && '.' != *ff_name(&ff))
  237.             {
  238.                   strcpy(new, path);
  239.                   if ('\\' != LAST_CHAR(new))
  240.                         strcat(new, "\\");
  241.                   strcat(new, ff_name(&ff));
  242.                   do_dir(new);
  243.             }
  244.       } while (Success_ == FIND_NEXT(&ff));
  245.       clean_dir(path);
  246.       if (gobble)
  247.             RMdir(path);
  248. }
  249.  
  250. /*
  251. **  File removal function - includes noaction switch and logging
  252. */
  253.  
  254. static void RMfile(char *fname)
  255. {
  256.       unsigned yr, mo, dy;
  257.  
  258.       if (!noaction)
  259.             remove(fname);
  260.       if (log)
  261.       {
  262.             scalar_to_ymd(file_date, &yr, &mo, &dy);
  263.             fprintf(log, "%02d/%02d/%04d: %s\n", mo, dy, yr, fname);
  264.       }
  265.       else  fprintf(stderr, "Deleting %s\n", fname);
  266. }
  267.  
  268. /*
  269. **  Directory removal function - includes noaction switch and logging
  270. */
  271.  
  272. static void RMdir(char *dname)
  273. {
  274.       if (!noaction)
  275.             rmdir(dname);
  276.       if (log)
  277.             fprintf(log, "Attempting to remove directory %s\n", dname);
  278. }
  279.  
  280. /*
  281. **  Error logging printf()
  282. */
  283.  
  284. static int log_printf(char *str, char *arg)
  285. {
  286.       FILE *out;
  287.  
  288.       if (log)
  289.             out = log;
  290.       else  out = stderr;
  291.  
  292.       return fprintf(out, str, arg);
  293. }
  294.